<template>
  <div class="chart-container">
    <!-- 工具栏 -->
    <div class="toolbar">
      <span class="sort-group">
        排序：
        <!-- 均分排序按钮 -->
        <!-- :class="{ active: sortKey === 'avgPopularity' }": 动态绑定CSS类，当sortKey等于'avgPopularity'时添加active类 -->
        <!-- @click="setSort('avgPopularity')": 点击事件，调用setSort函数并传入'avgPopularity'参数 -->
        <button
            :class="{ active: sortKey === 'avgPopularity' }"
            @click="setSort('avgPopularity')"
        >
          <!-- 按钮文本 -->
          <!-- {{ sortOrder.avgPopularity === 'asc' ? '↑' : '↓' }}: 条件渲染，根据sortOrder.avgPopularity的值显示↑或↓ -->
          所有作品平均热度 <span>{{ sortOrder.avgPopularity === 'asc' ? '↑' : '↓' }}</span>
        </button>
        <!-- 总票房排序按钮 -->
        <!-- :class="{ active: sortKey === 'sumRevenue' }": 动态绑定CSS类，当sortKey等于'sumRevenue'时添加active类 -->
        <!-- @click="setSort('sumRevenue')": 点击事件，调用setSort函数并传入'sumRevenue'参数 -->
        <button
            :class="{ active: sortKey === 'sumRevenue' }"
            @click="setSort('sumRevenue')"
        >
          <!-- 按钮文本 -->
          <!-- {{ sortOrder.sumRevenue === 'asc' ? '↑' : '↓' }}: 条件渲染，根据sortOrder.sumRevenue的值显示↑或↓ -->
          总票房 <span>{{ sortOrder.sumRevenue === 'asc' ? '↑' : '↓' }}</span>
        </button>
      </span>
    </div>

    <!-- 图表 -->
    <!-- ref="chartRef": 设置引用，可以通过this.$refs.chartRef访问该组件 -->
    <!-- :option="chartOption": 绑定图表配置选项 -->
    <!-- autoresize: 布尔属性，自动调整图表大小以适应容器 -->
    <v-chart ref="chartRef" :option="chartOption" autoresize />
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue'
import VChart from 'vue-echarts'
import * as echarts from 'echarts'

/* ---------- 1. 取数 ---------- */
const raw = ref([])
const loading = ref(false)

async function fetchData() {
  loading.value = true
  try {
    const res = await fetch('/api/queryDirectorByRevAndPop')
    if (!res.ok) throw new Error(res.status)
    const data = await res.json()
    raw.value = data.map(item => ({
      name: item.director,
      avgPopularity: item.avgPopularity,
      sumRevenue: item.sumRevenue
    }))
  } catch (e) {
    console.error('拉取导演数据失败', e)
  } finally {
    loading.value = false
  }
}
onMounted(() => fetchData())

/* ---------- 2. 排序 ---------- */
const sortKey = ref('avgPopularity')
const sortOrder = ref({ avgPopularity: 'desc', sumRevenue: 'desc' })

function toggle(key) {
  sortOrder.value[key] = sortOrder.value[key] === 'asc' ? 'desc' : 'asc'
}
function setSort(key) {
  sortKey.value = key
  toggle(key)
}
const sorted = computed(() => {
  if (!sortKey.value) return raw.value
  const key = sortKey.value
  const order = sortOrder.value[key]
  return [...raw.value].sort((a, b) =>
      order === 'asc' ? a[key] - b[key] : b[key] - a[key]
  )
})

/* ---------- 3. 映射 ---------- */
const voteMax = 10
const boxMax = 8.5e11
const mapVote = v => -(v / 1100) * voteMax
const mapBox  = v => (v / boxMax) * voteMax
const invVote = internal => -(internal / voteMax) * 1100
const invBox  = internal => (internal / voteMax) * boxMax

/* ---------- 4. 缩写函数 ---------- */
function autoAbbr(name) {
  return name
      .split(',')                       // 1. 按逗号分段
      .map(part => {
        const words = part.trim().split(/\s+/); // 2. 每段按空格拆块
        if (words.length === 1) return words[0]; // 只有一块，原样返回
        const last = words.pop();               // 最后一块（姓氏）保留全称
        const initials = words.map(w => w[0].toUpperCase() + '.').join(' '); // 前面块取首字母
        return initials + ' ' + last;          // 拼接：首字母缩写 + 空格 + 姓氏
      })
      .join(', ');                      // 3. 各段用逗号连回字符串
}

/* ---------- 5. 图表配置 ---------- */
const yAxisData = ref([])   // 响应式缩写数组

const chartOption = ref({
  title: { text: '导演平均热度 · 总票房 对比图', left: 'center', top: '10%' },
  grid: { top: '20%', bottom: 30, left: '12%', right: '10%' },
  xAxis: {
    type: 'value',
    position: 'top',
    min: -voteMax,
    max: voteMax,
    axisLabel: {
      formatter: val => {
        if (val <= 0) return invVote(val).toFixed(0)
        return (invBox(val) / 1e8).toFixed(1) + '亿'
      }
    }
  },
  yAxis: {
    type: 'category',
    axisLine: { show: false },
    axisTick: { show: false },
    data: yAxisData,
    axisLabel: { interval: 0, rotate: 0, margin: 0, right: 5 , fontSize: 9,}
  },
  tooltip: {
    trigger: 'axis',
    axisPointer: { type: 'shadow' },
    formatter: params => {
      const idx = params[0].dataIndex
      const rawItem = sorted.value[sorted.value.length - 1 - idx]
      return [
        `导演：${rawItem.name}`,
        `平均热度：${rawItem.avgPopularity.toFixed(1)}`,
        `总票房：${rawItem.sumRevenue.toLocaleString()}`
      ].join('<br/>')
    }
  },
  series: [
    {
      name: '均分',
      type: 'bar',
      data: [],
      label: { show: true, position: 'left', formatter: p => sorted.value[sorted.value.length - 1 - p.dataIndex].avgPopularity.toFixed(1) },
      itemStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{ offset: 0, color: '#69c0ff' }, { offset: 1, color: '#e6f7ff' }]),
        borderRadius: [6, 0, 0, 6]
      }
    },
    {
      name: '总票房',
      type: 'bar',
      data: [],
      label: { show: true, position: 'right', formatter: p => (sorted.value[sorted.value.length - 1 - p.dataIndex].sumRevenue / 1e8).toFixed(1) + '亿' },
      itemStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{ offset: 0, color: '#e7f3d3' }, { offset: 1, color: '#8bc34a' }]),
        borderRadius: [0, 6, 6, 0]
      },
      barGap: '-100%'
    }
  ]
})

/* ---------- 6. 数据 → 图表 ---------- */
watch(sorted, newVal => {
  const costData = []
  const revenueData = []
  // 缩写 + 反转
  yAxisData.value = newVal.map(item => autoAbbr(item.name)).reverse()
  newVal.forEach(item => {
    costData.push(mapVote(item.avgPopularity))
    revenueData.push(mapBox(item.sumRevenue))
  })
  chartOption.value.series[0].data = costData.reverse()
  chartOption.value.series[1].data = revenueData.reverse()
}, { immediate: true })
</script>

<style scoped>
/* 图表容器样式 */
.chart-container {
  /* 宽度设置为视口宽度的80% */
  width: 80vw;
  /* 高度设置为视口高度的80% */
  height: 80vh;  /* 增加图表容器高度 */
  /* 上边距设置为负的视口高度的20%，用于调整整体上移距离 */
  margin-top: -20vh;  /* 调整整体上移距离 */
}

/* 工具栏样式 */
.toolbar {
  /* 相对定位 */
  position: relative;
  /* 距离顶部的距离为视口高度的2% */
  top: 5vh;  /* 调整工具栏上移距离 */
  /* 使用flex布局并居中显示 */
  display: flex;
  /* 水平居中 */
  justify-content: center;
  /* 下边距为8像素 */
  margin-bottom: 8px;
  /* 字体大小为14像素 */
  font-size: 14px;
  /* 保证按钮在最上层，不会被图表遮挡 */
  z-index: 9999;
}

/* 媒体查询，当屏幕宽度小于等于768像素时应用 */
@media (max-width: 768px) {
  /* 图表容器样式 */
  .chart-container {
    /* 高度设置为300像素 */
    height: 300px;
  }
}

/* 排序按钮组中的按钮样式 */
.sort-group button {
  /* 左边距为6像素 */
  margin-left: 6px;
  /* 内边距，上下4像素，左右10像素 */
  padding: 4px 10px;
  /* 边框，1像素实线，颜色为#ccc */
  border: 1px solid #ccc;
  /* 形状：药丸形 */
  border-radius: 20px;
  /* 背景颜色为白色 */
  background: #fff;
  /* 鼠标指针样式为手型 */
  cursor: pointer;
}

/* 排序按钮组中激活状态的按钮样式 */
.sort-group button.active {
  /* 背景颜色为#409eff */
  background: #409eff;
  /* 文字颜色为白色 */
  color: #fff;
  /* 边框颜色为#409eff */
  border-color: #409eff;
}
</style>